#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include "Radius.h"
#include "radius_interface.h"
#include "aes.h"
#include "WinError.h"
#include "CRadiusMain.h"

#pragma comment (lib, "Ws2_32.lib")


int udp_packet_calculate_md5(char *packet_buffer, int packet_size, char *secret, int secret_length, char *md5_out)
{
    char *temp;
    temp = (char *)malloc(packet_size + secret_length);
    if (!temp)
    {
        return -1;
    }
    memcpy(temp, packet_buffer, packet_size);
    memcpy(temp + packet_size, secret, secret_length);
    fr_md5_calc((unsigned char *)md5_out, (unsigned char *)temp, packet_size + secret_length);
    free(temp);
    return 0;
}

int AES_read(int sock, char *buffer, int size,struct aes_ctx * paes)
{
    int p, loop;
    unsigned char temp[16] = {0};
    p = recv(sock, buffer, size, 0);
    if ((p == -1) || (p == 0))
    {
        return p;
    }
    if (!AES_align_size(p))
    {
        debug_printf("warning, server send error packet size: %d\n", p);
        return -1;
    }
    // align_size = AES_pad_align_size(p);
    for (loop = 0; loop < p / 16; loop++)
    {
        memset(temp , 0, 16);
        aes_decrypt(paes, temp, (unsigned char*)buffer + loop * 16);
        memcpy(buffer + loop * 16, temp, 16);
    }
    return p;
}

int AES_write(int sock, char *buffer, int size,struct aes_ctx * paes)
{
    int p, align_size, loop;
    unsigned char *temp, last[17] = {0};
    align_size = AES_pad_align_size(size);

    temp = (unsigned char *)malloc(align_size);
    if (!temp)
    {
        debug_printf("error AES_write malloc");
        return -1;
    }
    memset(temp , 0, align_size);
    for (loop = 0; loop < align_size / 16; loop++)
    {
        if (loop == align_size / 16 - 1)       //last aes block , padding 0 to match 16 bytes
        {
            memset(last, 0 ,16);
            memcpy(last, buffer + loop * 16, size - loop * 16);
            aes_encrypt(paes, temp + loop * 16, last);
        }
        else aes_encrypt(paes, temp + loop * 16, (unsigned char *) buffer + loop * 16);
    }
    p = send(sock, (char *)temp, align_size, 0);
    if (p == -1)
    {
        debug_printf ("error send AES packet\n");
    }
    free(temp);
    return p;
}
/*

LPSTR PrintError(int ErrorCode)
{
	static char Message[1024];

	// If this program was multi-threaded, we'd want to use
	// FORMAT_MESSAGE_ALLOCATE_BUFFER instead of a static buffer here.
	// (And of course, free the buffer when we were done with it)

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
		FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, ErrorCode,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		(LPSTR) Message, 1024, NULL);
	return Message;
}*/
